package com.hbisoft.pickit;

import ohos.app.Context;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

// This has not been tested extensively
// Feedback is needed from developers
// Some devices do not accept accessing the SD Card UID
// If the device doesn't allow using the UID, we have to replace it with the name of the SD Card.
public class SDUtil {
    private static final String EXTERNAL_STORAGE = System.getenv("EXTERNAL_STORAGE");
    private static final String SECONDARY_STORAGES = System.getenv("SECONDARY_STORAGE");
    private static final String EMULATED_STORAGE_TARGET = System.getenv("EMULATED_STORAGE_TARGET");
    private static final String SLASH = "/";

    public static String[] getStorageDirectories(Context context) {
        final Set<String> availableDirectoriesSet = new HashSet<>();

        if (!EMULATED_STORAGE_TARGET.isEmpty()) {
            availableDirectoriesSet.add(getEmulatedStorageTarget(context));
        } else {
            availableDirectoriesSet.addAll(getExternalStorage(context));
        }

        Collections.addAll(availableDirectoriesSet, getAllSecondaryStorages());
        String[] storagesArray = new String[availableDirectoriesSet.size()];
        return availableDirectoriesSet.toArray(storagesArray);
    }

    private static Set<String> getExternalStorage(Context context) {
        final Set<String> availableDirectoriesSet = new HashSet<>();
        File[] files = getExternalFilesDirs(context);
        for (File file : files) {
            if (file != null) {
                String applicationSpecificAbsolutePath = null;
                try {
                    applicationSpecificAbsolutePath = file.getCanonicalPath();
                } catch (IOException e) {

                }
                String rootPath = applicationSpecificAbsolutePath.substring(9, applicationSpecificAbsolutePath.indexOf("Android/data")
                );

                rootPath = rootPath.substring(rootPath.indexOf("/storage/") + 1);
                rootPath = rootPath.substring(0, rootPath.indexOf(SLASH));

                if (!rootPath.equals("emulated")) {
                    availableDirectoriesSet.add(rootPath);
                }
            }
        }
        return availableDirectoriesSet;
    }

    private static String getEmulatedStorageTarget(Context context) {
        String rawStorageId = "";
        final String path = context.getFilesDir().toString();
        final String[] folders = path.split(File.separator);
        final String lastSegment = folders[folders.length - 1];
        if (!lastSegment.isEmpty() && isDigitsOnly(lastSegment)) {
            rawStorageId = lastSegment;
        }

        if (rawStorageId.isEmpty()) {
            return EMULATED_STORAGE_TARGET;
        } else {
            return EMULATED_STORAGE_TARGET + File.separator + rawStorageId;
        }
    }

    private static boolean isDigitsOnly(String string){
        final int len = string.length();
        for (int cp, i = 0; i < len; i += Character.charCount(cp)) {
            cp = Character.codePointAt(string, i);
            if (!Character.isDigit(cp)) {
                return false;
            }
        }
        return true;
    }


    private static String[] getAllSecondaryStorages() {
        if (!SECONDARY_STORAGES.isEmpty()) {
            return SECONDARY_STORAGES.split(File.pathSeparator);
        }
        return new String[0];
    }

    private static List<String> getAvailablePhysicalPaths() {
        List<String> availablePhysicalPaths = new ArrayList<>();
        for (String physicalPath : KNOWN_PHYSICAL_PATHS) {
            File file = new File(physicalPath);
            if (file.exists()) {
                availablePhysicalPaths.add(physicalPath);
            }
        }
        return availablePhysicalPaths;
    }

    private static File[] getExternalFilesDirs(Context context) {
        return context.getExternalFilesDirs(null);
    }

    @SuppressWarnings("SpellCheckingInspection")
    private static final String[] KNOWN_PHYSICAL_PATHS = new String[]{
            "/storage/sdcard0",
            "/storage/sdcard1",
            "/storage/extsdcard",
            "/storage/sdcard0/external_sdcard",
            "/mnt/extsdcard",
            "/mnt/sdcard/external_sd",
            "/mnt/sdcard/ext_sd",
            "/mnt/external_sd",
            "/mnt/media_rw/sdcard1",
            "/removable/microsd",
            "/mnt/emmc",
            "/storage/external_SD",
            "/storage/ext_sd",
            "/storage/removable/sdcard1",
            "/data/sdext",
            "/data/sdext2",
            "/data/sdext3",
            "/data/sdext4",
            "/sdcard1",
            "/sdcard2",
            "/storage/microsd"
    };
}

